package com.zlm.user.emp.service.impl;

import com.zlm.amqp.conf.RabbitConfig;
import com.zlm.common.constants.CodeConstants;
import com.zlm.common.constants.CommonConstants;
import com.zlm.common.constants.UserConstants;
import com.zlm.common.enums.MarriedEnum;
import com.zlm.common.enums.SexEnum;
import com.zlm.common.enums.VerifyStatusEnum;
import com.zlm.common.util.*;
import com.zlm.huanxin.util.HuanxinUtils;
import com.zlm.user.emp.dao.SysEmpDao;
import com.zlm.user.emp.entity.SysEmpDO;
import com.zlm.user.emp.entity.dto.LoginAppParamsDto;
import com.zlm.user.emp.dao.SysActivationDao;
import com.zlm.user.emp.dao.UserTokenDao;
import com.zlm.common.entity.SysActivationDO;
import com.zlm.common.entity.UserTokenDO;
import com.zlm.common.dto.userEmp.SysEmpDto;
import com.zlm.user.emp.service.LoginService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 登录服务实现类
 *
 * @Author: duyufu
 * @Date: 2019/4/12 9:35
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private SysActivationDao sysActivationDao;
    @Autowired
    private SysEmpDao sysEmpDao;
    @Autowired
    private UserTokenDao userTokenDao;

    @Override
    public boolean checkMobile(String mobile) {
        if (null == mobile || !RegexUtils.isMobileSimple(mobile)) {
            return false;
        }
        return true;
    }

    /**
     * 校验验证码
     *
     * @param activationCode
     * @param mobile
     * @return
     */
    public Pair<Boolean, String> checkActivation(String activationCode, String mobile) {
        SysActivationDO activation = new SysActivationDO();
        activation.setMobile(mobile);
        SysActivationDO sysActivationDO = sysActivationDao.getActivation(activation);
        if (null == sysActivationDO || !activationCode.equals(sysActivationDO.getCode())) {
            return Pair.of(false, CodeConstants.CODE_10002);
        }
        //验证码是否实效
        Long currentTime = DateTimeUtils.getCurrentTimestamp().getTime();
        Long validTime = sysActivationDO.getValidTime().getTime();
        if (currentTime > validTime) {
            return Pair.of(false, CodeConstants.CODE_10005);
        }
        sysActivationDao.changeStatus(sysActivationDO.getId());
        return Pair.of(true, "");
    }

    /**
     * 检查密码登录参数
     *
     * @param loginAppParamsDto
     * @return
     */
    @Override
    public Pair<Boolean, String> checkLoginPwdParams(LoginAppParamsDto loginAppParamsDto) {
        if (!checkMobile(loginAppParamsDto.getMobile())) {
            return Pair.of(false, CodeConstants.CODE_10001);
        }
        if (StringUtils.isBlank(loginAppParamsDto.getPassword())) {
            return Pair.of(false, CodeConstants.CODE_10003);
        }
        return Pair.of(true, "");
    }

    /**
     * 绑定手机号
     * @param loginAppParamsDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> bindMobile(LoginAppParamsDto loginAppParamsDto) {
        SysEmpDO emp = new SysEmpDO();
        //判断登录类型
        if (CommonConstants.WECHAT_LOGIN.intValue() == loginAppParamsDto.getLoginType().intValue()) {
            emp.setWechatOpenid(loginAppParamsDto.getOpenid());
        }else if(CommonConstants.QQ_LOGIN.intValue() == loginAppParamsDto.getLoginType().intValue()) {
            emp.setQqOpenid(loginAppParamsDto.getOpenid());
        }
        emp.setMobile(loginAppParamsDto.getMobile());
        int existEmp = sysEmpDao.isExistEmp(loginAppParamsDto.getMobile());
        if (existEmp == 0){
            sysEmpDao.tencentBindMobile(emp);
        } else if (existEmp == 1){
            sysEmpDao.deleteEmp(emp);
            sysEmpDao.bindMobile(emp);
        }else {
            throw new RuntimeException(CodeConstants.CODE_FAIL);
        }
        SysEmpDto sysEmpDto = sysEmpDao.selectEmp(emp);
        Map<String, Object> login = new HashMap<>(2);
        UserTokenDO userToken = saveToken(loginAppParamsDto.getMobile(),sysEmpDto.getEmpId());
        login.put("token",userToken.getToken());
        login.put("loginEmp",sysEmpDto);
        return login;
    }

    /**
     * 保存token
     * @param mobile
     * @param empId
     * @return
     */
    private UserTokenDO saveToken(String mobile,Integer empId) {
        String newToken = TokenUtils.createToken(mobile);
        UserTokenDO userToken = new UserTokenDO();
        userToken.setUserId(empId);
        userToken.setToken(newToken);
        userToken.setMobile(mobile);
        userToken.setUserType(UserConstants.USER_TYPE_EMP);
        userToken.setAlive(1);
        int token = userTokenDao.getEmpToken(mobile);
        if (token==0){
            userTokenDao.saveUserToken(userToken);
        } else {
            userTokenDao.updateUserToken(userToken);
        }
        return userToken;
    }

    /**
     * 根据手机查询用户并生成token并登陆
     * @param mobile
     * @return
     */
    @Override
    public SysEmpDto loginEmp(String mobile) {
        Map<String, Object> map = new HashMap<>();
        map.put("mobile",mobile);
        List<SysEmpDto> sysEmpList = sysEmpDao.queryEmp(map);
        //登录成功
        if (null != sysEmpList && sysEmpList.size() == 1) {
            SysEmpDto user = sysEmpList.get(0);
            SysEmpDto sysEmpDto = completEmpDto(user);
            UserTokenDO userToken = saveToken(mobile,user.getEmpId());
            sysEmpDto.setToken(userToken.getToken());
            return sysEmpDto;
        }else {
            throw new RuntimeException(CodeConstants.CODE_FAIL);
        }

    }

    /**
     * 注册用户
     * @param mobile
     * @param password
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysEmpDto registerEmp(String mobile, String password) {
        SysEmpDO user = new SysEmpDO();
        user.setMobile(mobile);
        user.setUserPwd(MD5Utils.getStringMD5(password));
        sysEmpDao.insertEmp(user);
        Integer empId = user.getEmpId();
        SysEmpDto sysEmpDto = completEmpDto(sysEmpDao.selectEmp(user));
        UserTokenDO userToken = saveToken(mobile,empId);
        sysEmpDto.setToken(userToken.getToken());
        return sysEmpDto;
    }

    /**
     * 验证码注册
     * @param mobile
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysEmpDto activationLogin(String mobile) {
        SysEmpDO user = new SysEmpDO();
        user.setMobile(mobile);
        sysEmpDao.insertEmp(user);
        Integer empId = user.getEmpId();
        SysEmpDto sysEmpDto = completEmpDto(sysEmpDao.selectEmp(user));
        UserTokenDO userToken = saveToken(mobile,empId);
        sysEmpDto.setToken(userToken.getToken());
        return sysEmpDto;
    }

    /**
     * 环信注册
     * @param userId
     */
    @Override
    public void huanxinRegister(Integer userId) {
        String username = UserConstants.USER_TYPE_EMP_STRING.concat(userId.toString());
        String queueName = RabbitConfig.HX_EMP_REGISTER;
        //环信注册
        HuanxinUtils.huanxinRegister(userId,username,queueName);
    }

    @Override
    public void huanxinDisconnect(String userHxId) {
        HuanxinUtils.disconnect(userHxId);
    }

    /**
     * 腾讯(QQ,微信)登录
     * @param emp
     * @return
     */
    @Override
    public Map<String, Object> tencentLogin(SysEmpDO emp) {
        SysEmpDto user = sysEmpDao.selectEmp(emp);
        Map<String, Object> login = new HashMap<>(2);
        SysEmpDto sysEmpDto = completEmpDto(user);
        if (StringUtils.isBlank(user.getMobile())) {
            login.put("token",null);
            login.put("loginEmp",sysEmpDto);
            login.put("bindStatus", 0);
        }else {
            UserTokenDO userToken = saveToken(user.getMobile(),user.getEmpId());
            login.put("token",userToken.getToken());
            login.put("loginEmp",sysEmpDto);
            login.put("bindStatus", 1);
        }
        return login;
    }



    /**
     * 补全用户信息
     * @param user
     * @return
     */
    private SysEmpDto completEmpDto(SysEmpDto user) {
        if (StringUtils.isBlank(user.getEmpName())) {
            user.setEmpName(UserConstants.USER_DEFAULT_NAME);
        }
        if (null != user.getSex()) {
            user.setSexName(SexEnum.getNameByCode(user.getSex()));
        }
        if (null != user.getMarried()) {
            user.setMarriedName(MarriedEnum.getNameByCode(user.getMarried()));
        }
        if (null != user.getStatus()) {
            user.setStatusName(VerifyStatusEnum.getNameByCode(user.getStatus()));
        }
        if (StringUtils.isNotBlank(user.getIdNo())) {
            user.setAge(IDCardUtils.getAgeByIdNo(user.getIdNo()));
        }
        if (StringUtils.isBlank(user.getEmpName())) {
            user.setEmpName(UserConstants.USER_DEFAULT_NAME);
        }
        return user;
    }
}
